package com.e3.core.utils;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;

/**
 * 日期处理工具类
 * 
 * @author <a href="mailto:yang_y@sysnet.com.cn">Young Yang</a>
 */
public class CalendarUtils {
	// 系统最小日期
	public static final Date MIN_DATE = MIN_DATE();
	// 系统最大日期
	public static final Date MAX_DATE = MAX_DATE();
	// 系统理论空日期
	public static final Date NULL_DATE = MIN_DATE;

	private final static SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");

	private static Date MIN_DATE() {
		Calendar thisCalendar = Calendar.getInstance();
		thisCalendar.set(1900, 0, 1, 0, 0, 0);
		thisCalendar.set(Calendar.MILLISECOND, 0);
		return thisCalendar.getTime();
	}

	private static Date MAX_DATE() {
		Calendar thisCalendar = Calendar.getInstance();
		thisCalendar.set(2999, 11, 31, 0, 0, 0); // 2999-12-31 00:00:00
		thisCalendar.set(Calendar.MILLISECOND, 0);
		return thisCalendar.getTime();
	}

	/**
	 * 增加或者减少年份
	 * 
	 * @param date 当前时间
	 * @param year 年份，正数为加，负数为减
	 */
	public static Date toYear(Date date, int year) {
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		calendar.add(Calendar.YEAR, year);
		return calendar.getTime();
	}

	/**
	 * 判断是否是同一年
	 */
	public static boolean sameYear(long thisTime, long thatTime) {
		Calendar thisCalendar = Calendar.getInstance();
		thisCalendar.setTimeInMillis(thisTime);

		Calendar thatCalendar = Calendar.getInstance();
		thatCalendar.setTimeInMillis(thatTime);
		return thisCalendar.get(Calendar.YEAR) == thatCalendar.get(Calendar.YEAR);
	}

	/**
	 * 判断是否是同一月
	 */
	public static boolean sameMonth(long thisTime, long thatTime) {
		Calendar thisCalendar = Calendar.getInstance();
		thisCalendar.setTimeInMillis(thisTime);

		Calendar thatCalendar = Calendar.getInstance();
		thatCalendar.setTimeInMillis(thatTime);
		return thisCalendar.get(Calendar.YEAR) == thatCalendar.get(Calendar.YEAR) && thisCalendar.get(Calendar.MONTH) == thatCalendar.get(Calendar.MONTH);
	}

	/**
	 * 判断是否是同一天
	 */
	public static boolean sameDate(long thisTime, long thatTime) {
		Calendar thisCalendar = Calendar.getInstance();
		thisCalendar.setTimeInMillis(thisTime);

		Calendar thatCalendar = Calendar.getInstance();
		thatCalendar.setTimeInMillis(thatTime);
		return thisCalendar.get(Calendar.YEAR) == thatCalendar.get(Calendar.YEAR) && thisCalendar.get(Calendar.MONTH) == thatCalendar.get(Calendar.MONTH) && thisCalendar.get(Calendar.DATE) == thatCalendar.get(Calendar.DATE);
	}

	/**
	 * 日期跳转，正数为加，负数为减
	 */
	public static Date toDate(Date thisDate, int count) {
		Calendar thisCalendar = Calendar.getInstance();
		thisCalendar.setTime(thisDate);

		int date = thisCalendar.get(Calendar.DAY_OF_MONTH);

		thisCalendar.set(Calendar.DATE, date + count);
		return thisCalendar.getTime();

	}

	/**
	 * 增加或者减少月份
	 * 
	 * @param date 当前时间
	 * @param month 月份，正数为加，负数为减
	 */
	public static Date toMonth(Date date, int month) {
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		calendar.add(Calendar.MONTH, month);
		return calendar.getTime();
	}

	/**
	 * 增加或者减少分钟数
	 * 
	 * @param date 当前时间
	 * @param count 分钟数，正数为加，负数为减
	 */
	public static Date toHour(Date date, int count) {
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		calendar.add(Calendar.HOUR_OF_DAY, count);
		return calendar.getTime();
	}

	/**
	 * 增加或者减少小时数
	 * 
	 * @param date 当前时间
	 * @param count 小时数，正数为加，负数为减
	 */
	public static Date toMinute(Date date, int count) {
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		calendar.add(Calendar.MINUTE, count);
		return calendar.getTime();
	}

	/**
	 * 增加或者减少周数
	 * 
	 * @param date 当前时间
	 * @param week 周数，正数为加，负数为减
	 */
	public static Date toWeek(Date date, int week) {
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		calendar.add(Calendar.WEEK_OF_MONTH, week);
		return calendar.getTime();
	}

	/**
	 * 用默认的 pattern "yyyy-MM-dd" 格式化
	 */
	public static String formatDate(Date date) {
		return dateFormat.format(date);
	}

	/**
	 * 指定 pattern 格式话
	 * 
	 * @param pattern 参考："yyyyMMddHHmmssSSS"
	 */
	public static String formatDate(String pattern, Date date) {
		return new SimpleDateFormat(pattern).format(date);
	}

	/**
	 * 将某一格式的字符串转化成日期
	 * 
	 * @param date
	 * @param fmt 参考："yyyyMMddHHmmssSSS"
	 * @return
	 * @throws Exception
	 */
	public static Date transStringToDate(String date, String fmt) throws Exception {
		SimpleDateFormat dateFormat = new SimpleDateFormat(fmt);
		return dateFormat.parse(date);
	}

	/**
	 * 将日期转化成某一个格式的字符串
	 * 
	 * @param date
	 * @param fmt 参考："yyyyMMddHHmmssSSS"
	 * @return
	 */
	public static String transDateToString(Date date, String fmt) {
		return formatDate(fmt, date);
	}

	/**
	 * return the previous day of the specific day. 返回指定日期的前面一天
	 * 
	 * @param baseDate
	 * @param fmt
	 * @return
	 */
	public static Date getBeforeDay(String baseDate, String fmt) {
		Calendar cal = java.util.Calendar.getInstance();
		SimpleDateFormat simple = new SimpleDateFormat(fmt);
		Date tempDate = null;
		try {
			tempDate = simple.parse(baseDate);
		}
		catch (ParseException e) {
			e.printStackTrace();
		}

		cal.set(getYear(tempDate), getMonth(tempDate), getDay(tempDate));
		cal.add(java.util.Calendar.DAY_OF_MONTH, -1);
		java.text.SimpleDateFormat sdf = new java.text.SimpleDateFormat(fmt);
		String beforeday = sdf.format(cal.getTime());
		try {
			return sdf.parse(beforeday);
		}
		catch (ParseException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			return null;
		}
	}

	/**
	 * 返回年份
	 * 
	 * @param date 日期
	 * @return 返回年份
	 */
	public static int getYear(java.util.Date date) {
		java.util.Calendar c = java.util.Calendar.getInstance();
		c.setTime(date);
		return c.get(java.util.Calendar.YEAR);
	}

	/**
	 * 返回月份
	 * 
	 * @param date 日期
	 * @return 返回月份
	 */
	public static int getMonth(java.util.Date date) {
		java.util.Calendar c = java.util.Calendar.getInstance();
		c.setTime(date);
		return c.get(java.util.Calendar.MONTH);
	}

	/**
	 * return what day of a week. 返回星期几
	 * 
	 * @param date
	 * @return
	 */
	public static int getDayOfWeek(java.util.Date date) {
		java.util.Calendar c = java.util.Calendar.getInstance();
		c.setTime(date);
		return c.get(java.util.Calendar.DAY_OF_WEEK);
	}

	/**
	 * return the total days of the specified month 返回一个月的总天数
	 * 
	 * @param date
	 * @return
	 */
	public static int getDaysOfMonth(java.util.Date date) {
		java.util.Calendar c = java.util.Calendar.getInstance();
		c.setTime(date);
		return c.getActualMaximum(Calendar.DAY_OF_MONTH);
		
	}

	/**
	 * 返回日份
	 * 
	 * @param date 日期
	 * @return 返回日份
	 */
	public static int getDay(java.util.Date date) {
		java.util.Calendar c = java.util.Calendar.getInstance();
		c.setTime(date);
		return c.get(java.util.Calendar.DAY_OF_MONTH);
	}

	/**
	 * 返回小时
	 * 
	 * @param date 日期
	 * @return 返回小时
	 */
	public static int getHour(java.util.Date date) {
		java.util.Calendar c = java.util.Calendar.getInstance();
		c.setTime(date);
		return c.get(java.util.Calendar.HOUR_OF_DAY);
	}

	/**
	 * 返回分钟
	 * 
	 * @param date 日期
	 * @return 返回分钟
	 */
	public static int getMinute(java.util.Date date) {
		java.util.Calendar c = java.util.Calendar.getInstance();
		c.setTime(date);
		return c.get(java.util.Calendar.MINUTE);
	}

	/**
	 * 返回秒钟
	 * 
	 * @param date 日期
	 * @return 返回秒钟
	 */
	public static int getSecond(java.util.Date date) {
		java.util.Calendar c = java.util.Calendar.getInstance();
		c.setTime(date);
		return c.get(java.util.Calendar.SECOND);
	}

	/**
	 * 返回毫秒
	 * 
	 * @param date 日期
	 * @return 返回毫秒
	 */
	public static long getMillis(java.util.Date date) {
		java.util.Calendar c = java.util.Calendar.getInstance();
		c.setTime(date);
		return c.getTimeInMillis();
	}

	public static boolean isLastDayOfMonth(java.util.Date date) {
		java.util.Calendar c = java.util.Calendar.getInstance();
		c.setTime(date);
		int month = c.get(java.util.Calendar.MONTH);

		Date nextDay = toDate(date, 1);
		c.setTime(nextDay);
		int month1 = c.get(java.util.Calendar.MONTH);

		return month == month1 ? false : true;
	}

	public static int getDaysBetween(Date date1, Date date2) {
		java.util.Calendar d1 = java.util.Calendar.getInstance();
		java.util.Calendar d2 = java.util.Calendar.getInstance();
		d1.setTime(date1);
		d2.setTime(date2);

		if (d1.after(d2)) {
			java.util.Calendar swap = d1;
			d1 = d2;
			d2 = swap;
		}

		int days = d2.get(java.util.Calendar.DAY_OF_YEAR) - d1.get(java.util.Calendar.DAY_OF_YEAR);
		int y2 = d2.get(java.util.Calendar.YEAR);

		if (d1.get(java.util.Calendar.YEAR) != y2) {
			d1 = (java.util.Calendar) d1.clone();
			do {
				days += d1.getActualMaximum(java.util.Calendar.DAY_OF_YEAR);
				d1.add(java.util.Calendar.YEAR, 1);
			}
			while (d1.get(java.util.Calendar.YEAR) != y2);
		}
		return days;
	}

	public static void main(String[] args) {
		System.out.println(formatDate(getDate(2009,0,1)));
	}

	/**
	 * 返回时间，时分秒都是0
	 * 
	 * @param year
	 * @param month 月是从0开始的
	 * @param day
	 * @return
	 */
	public static Date getDate(int year, int month, int day) {
		return getDate(year, month, day, 0, 0, 0);
	}

	public static Date getDate(int year, int month, int day, int hour, int min, int sec) {
		Calendar calendar = Calendar.getInstance();
		calendar.set(Calendar.YEAR, year);
		calendar.set(Calendar.MONTH, month);
		calendar.set(Calendar.DAY_OF_MONTH, day);
		calendar.set(Calendar.HOUR_OF_DAY, hour);
		calendar.set(Calendar.MINUTE, min);
		calendar.set(Calendar.SECOND, sec);
		calendar.set(Calendar.MILLISECOND, 0);
		return calendar.getTime();
	}
}
